home *** CD-ROM | disk | FTP | other *** search
- Path: news.larc.nasa.gov!amiga-request
- From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
- Subject: v91i074: Browser 1.7 - a programmer's "Workbench", Part01/01
- Reply-To: peter@taronga.hackercorp.com
- Newsgroups: comp.sources.amiga
- Message-ID: <comp.sources.amiga:v91i074@ab20.larc.nasa.gov>
- Date: 25 Mar 91 15:44:34 GMT
- Approved: tadguy@uunet.UU.NET (Tad Guy)
- X-Mail-Submissions-To: amiga@uunet.uu.net
- X-Post-Discussions-To: comp.sys.amiga.misc
-
- Submitted-by: peter@taronga.hackercorp.com
- Posting-number: Volume 91, Issue 074
- Archive-name: utilities/browser-1.7/part01
-
- Well, 1.4 is now 2.0, and it's almost here. So this is probably going to
- be the last revision of Browser. I'm now using Workbench 2.0 on a daily
- basis, and I find I'm not using Browser that much. It remains faster than
- workbench and cleaner for quick jobs, but not enough for me to spend much
- time on it. However, lots of people remain in a 1.3 environment, and with
- the new release of the Aztec C compiler (5.0d) I've been able to clear up
- several outstanding bugs in Browser. Thus, the new release.
-
- What Browser does allow you to do, easily and conveniently, is to
- move, copy, rename, and delete files and directories. It will also let you
- execute either Workbench or CLI programs, either directly by double-
- clicking them or by selecting them from a menu. By combining these you can
- set up a complete operating environment that will, to a large extent,
- replace both Workbench and the CLI.
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: PatMatch.c browser.doc fonts.h goodies.readme menu.c
- # menu.h vollist.c
- # Wrapped by tadguy@ab20 on Mon Mar 25 10:44:32 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'PatMatch.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'PatMatch.c'\"
- else
- echo shar: Extracting \"'PatMatch.c'\" \(5837 characters\)
- sed "s/^X//" >'PatMatch.c' <<'END_OF_FILE'
- X/* PatMatch.c - Implements AmigaDos Regular Expression Pattern Matching.
- X**
- X** This program will test whether a string is an AmigaDos regular expression
- X** It may be used to implement wild expressions such as:
- X**
- X** "copy #?.c to <dir>" to copy any file ending in .c
- X**
- X** The program has two entry points: CmplPat, and Match.
- X**
- X** CmplPat - takes a pattern and returns an auxilliary integer vector
- X** which is used by Match. The pattern is not modified in
- X** any way. CmplPat returns 1 if no errors were detected
- X** while compiling the pattern; otherwise it returns 0;
- X**
- X** Match - takes the pattern, the auxilliary vector, and the string
- X** to be matched. It returns 1 if the string matches the
- X** pattern; otherwise it returns 0;
- X**
- X** Translated from BCPL by:
- X** Jeff Lydiatt
- X** Richmond B.C. Canada
- X** 16 May 1986.
- X**
- X** Source: "A Compact Function for Regular Expression Pattern Matching",
- X** Software - Practice and Experience, September 1979.
- X**
- X** Useage:
- X** To test if "file.c" matches the regular expression "#?.c"
- X** char *Pat = "#?.c";
- X** char *Str = "file.c";
- X** WORD Aux[128];
- X**
- X** if ( CmplPat( Pat, Aux ) == 0 )
- X** {
- X** printf("Bad Wildcard Expression\n");
- X** exit(1);
- X** }
- X** if ( Match( Pat, Aux, Str ) == 1 )
- X** printf("String matches the pattern\n");
- X** else
- X** printf("String does NOT match the pattern\n");
- X**/
- X
- X/*--- Included files ----*/
- X
- X#include <stdio.h>
- X#include <exec/types.h>
- X#include <ctype.h>
- X
- X#define EOS '\0'
- X
- X/*--- Global Variables ---*/
- X
- Xstatic char Ch; /* The current character in Pattern */
- Xstatic char *Pat; /* Pointer to the Pattern */
- Xstatic WORD *Aux; /* Pointer to returned auxilliary vector */
- Xstatic int PatP; /* Current position in Pat */
- Xstatic int Patlen; /* strlen(pat) */
- Xstatic BOOL Errflag; /* TRUE if error */
- Xstatic WORD *Work; /* Pointer to Active work area */
- Xstatic int Wp; /* Current position in work */
- Xstatic BOOL Succflag;/* True if "str" matches "pat" */
- X
- X/*----------------------------------------------------------------*/
- X/* The Interpreter */
- X/*----------------------------------------------------------------*/
- X
- Xstatic void Put(int N)
- X{
- X register WORD *ip;
- X register WORD *to;
- X
- X if ( N == 0 )
- X Succflag = TRUE;
- X else
- X {
- X for ( ip = &Work[ 1 ], to = &Work[ Wp ]; ip <= to; ip++)
- X if ( *ip == N )
- X return;
- X Work[ ++Wp ] = N;
- X }
- X}
- X
- Xint Match( char *Pat, WORD *Aux, char *Str )
- X{
- X static WORD W[ 128 ];
- X int S = 0;
- X int I, N, Q, P, Strlength;
- X char K;
- X int strlen();
- X void Put();
- X
- X Work = W;
- X Wp = 0;
- X Succflag = FALSE;
- X Strlength = strlen( Str );
- X Put( 1 );
- X
- X if ( Aux[ 0 ] != 0 )
- X Put( Aux[ 0 ] );
- X
- X for(;;)
- X {
- X /* First complete the closure */
- X for( N=1; N <= Wp; N++ )
- X {
- X P = Work[ N ];
- X K = Pat[ P-1 ];
- X Q = Aux[ P ];
- X switch( K )
- X {
- X case '#': Put( P + 1 );
- X case '%': Put( Q );
- X default : break;
- X case '(':
- X case '|': Put( P + 1);
- X if ( Q != 0 )
- X Put( Q );
- X }
- X }
- X
- X if ( S >= Strlength )
- X return Succflag;
- X if ( Wp == 0 )
- X return FALSE;
- X Ch = Str[ S++ ];
- X
- X /* Now deal with the match items */
- X
- X N = Wp;
- X Wp = 0;
- X Succflag = FALSE;
- X
- X for ( I = 1; I <= N; I++)
- X {
- X P = Work[ I ];
- X K = Pat[ P - 1 ];
- X switch( K )
- X {
- X case '#':
- X case '|':
- X case '%':
- X case '(': break;
- X case '\'': K = Pat[ P ];
- X default : if ( _toupper( Ch ) != _toupper( K ) )
- X break;
- X case '?': /* Successful match */
- X Put ( Aux[ P ] );
- X } /* End Switch */
- X } /* End For I */
- X } /* End for(;;) */
- X}
- X
- X
- X/*----------------------------------------------------------------*/
- X/* The Compiler */
- X/*----------------------------------------------------------------*/
- X
- Xstatic void Rch(void) /* Read next character from Pat */
- X{
- X if ( PatP >= Patlen )
- X Ch = EOS;
- X else
- X Ch = Pat[ PatP++ ];
- X}
- X
- Xstatic void Nextitem(void) /* Get next char from Pat; recognize the ' escape char */
- X{
- X if ( Ch == '\'' )
- X Rch();
- X Rch();
- X}
- X
- Xstatic void Setexits( int List, int Val )
- X{
- X int A;
- X
- X do
- X {
- X A = Aux[ List ];
- X Aux[ List ] = Val;
- X List = A;
- X }
- X while ( List != 0 );
- X}
- X
- Xstatic int Join( int A, int B )
- X{
- X int T = A;
- X
- X if ( A == 0 )
- X return B;
- X while ( Aux[ A ] != 0 )
- X A = Aux[ A ];
- X Aux[ A ] = B;
- X return T;
- X}
- X
- Xstatic int Prim(void) /* Parse a Prim symbol */
- X{
- X int A = PatP;
- X char Op = Ch;
- X int Exp();
- X void Setexits(), Nextitem();
- X
- X Nextitem();
- X switch( Op )
- X {
- X case EOS:
- X case ')':
- X case '|': Errflag = TRUE;
- X default : return A;
- X case '#': Setexits( Prim(), A ); return A;
- X case '(': A = Exp( A );
- X if ( Ch != ')' )
- X {
- X Errflag = TRUE;
- X }
- X Nextitem();
- X return A;
- X }
- X}
- X
- Xstatic int Exp( int AltP ) /* Parse an expression */
- X{
- X int Exits = 0;
- X int A;
- X int Prim(), Exits(), Join();
- X void Nextitem(), Setexits();
- X
- X for (;;)
- X {
- X A = Prim();
- X if ( Ch == '|' || Ch == ')' || Ch == EOS )
- X {
- X Exits = Join( Exits, A );
- X if ( Ch != '|' )
- X return Exits;
- X Aux[ AltP ] = PatP;
- X AltP = PatP;
- X Nextitem();
- X }
- X else
- X Setexits( A, PatP );
- X }
- X}
- X
- Xint CmplPat( char *Pattern, WORD *CmplPattern)
- X{
- X int i, strlen();
- X void Rch(), Setexits();
- X
- X Pat = Pattern;
- X Aux = CmplPattern;
- X PatP = 0;
- X Patlen = strlen( Pat );
- X Errflag = FALSE;
- X
- X for ( i = 0; i <= Patlen; i++ )
- X Aux[ i ] = 0;
- X Rch();
- X Setexits( Exp(0), 0 );
- X return (!Errflag);
- X}
- END_OF_FILE
- if test 5837 -ne `wc -c <'PatMatch.c'`; then
- echo shar: \"'PatMatch.c'\" unpacked with wrong size!
- fi
- # end of 'PatMatch.c'
- fi
- if test -f 'browser.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'browser.doc'\"
- else
- echo shar: Extracting \"'browser.doc'\" \(12580 characters\)
- sed "s/^X//" >'browser.doc' <<'END_OF_FILE'
- XBrowser -- a programmer's "Workbench". Release 1.7
- X
- X) 1990 Peter da Silva
- X
- XIntroduction
- X
- X In earlier versions of Browser, I opened this document with the
- Xsomewhat confident comment:
- X
- X The Amiga "Workbench" has some serious deficiencies as
- X a working environment. The most important one is that
- X it doesn't let you operate on just any file (this is
- X rumored to be fixed in 1.4, by the way), but there are
- X others. It's designed to be easy to learn and use, but
- X it just isn't very powerful.
- X
- XWell, 1.4 is now 2.0, and it's almost here. So this is probably going to
- Xbe the last revision of Browser. I'm now using Workbench 2.0 on a daily
- Xbasis, and I find I'm not using Browser that much. It remains faster than
- Xworkbench and cleaner for quick jobs, but not enough for me to spend much
- Xtime on it. However, lots of people remain in a 1.3 environment, and with
- Xthe new release of the Aztec C compiler (5.0d) I've been able to clear up
- Xseveral outstanding bugs in Browser. Thus, the new release.
- X
- X This program is an attempt to deal with limitations in earlier
- Xversions of the Workbench. It runs under all versions of AmigaOS, including
- X2.0, but is expected to be most useful for people running 1.3 and earlier.
- XIt is not a complete replacement for Workbench, nor is it intended to be.
- XThere is no attempt to support icons, and there are no disk-oriented
- Xfunctions (formatting, copying, etc...).
- X
- X What Browser does allow you to do, easily and conveniently, is to
- Xmove, copy, rename, and delete files and directories. It will also let you
- Xexecute either Workbench or CLI programs, either directly by double-
- Xclicking them or by selecting them from a menu. By combining these you can
- Xset up a complete operating environment that will, to a large extent,
- Xreplace both Workbench and the CLI.
- X
- X Browser presents you with a set of windows, representing directories,
- Xwith all the files and directories within each listed in alphabetical
- Xorder. Directories, displayed in color 2 (red/orange), are listed first,
- Xfollowed by the files. Selected files are displayed in inverse video.
- X
- XSelecting Files
- X
- X You can select individual files three ways. First, just click on
- Xa file name. This will select that file and deselect all others. If you
- Xhold down the shift key when you click on the file, it will be selected
- Xwithout deselecting other files. This way you can build a list of files
- Xto operate on. So far this is just like Workbench, but if you click a
- Xselected file while holding down the shift key, it will be deselected
- Xwithout affecting other selected files. This lets you take back mistakes.
- X
- X Finally, you can use the menu items "Sel All" and "Sel Match" to
- Xselect a group of files at once. "Sel All" will select all files in the
- Xactive window. "Sel Match" will allow you to enter a pattern and then
- Xselect only files matching that pattern in the active window. These
- Xnormally act as toggles... if you have any selected files in the active
- Xwindow they will be deselected if they match.
- X
- XActions
- X
- X There are, again, three ways to manipulate selected files. First,
- Xyou can drag a file or selected files to another window by holding down the
- Xleft mouse button while you move the mouse. When you release the button,
- XBrowser will attempt to move the files to the location you indicate. This
- Xis just like the Workbench.
- X
- X Secondly, double-clicking a file will open it. If it's a directory,
- Xit will be opened and files in it will be displayed. If it's a program
- Xwith an accompanying '.info' file, it will be launched as a Workbench task.
- XThis will also work with Projects, if the accompanying .info file specifies
- Xa tool. Finally, Browser will ask you if you want to launch it as a CLI
- Xprogram.
- X
- X Any other files selected will be passed to the new program, either
- Xon the CLI command line or in the Workbench Args structure. This is the
- Xnormal Workbench shift-double-click method.
- X
- X Third, you can select a menu item.
- X
- XMenus
- X
- X There are two main Browser menus. The first, "Browser", relates to
- Xthe browser environment itself. The second, "Actions", relates to the files
- Xand directories displayed in Browser's windows. Menu items act either on
- Xselected files or on the currently active window. There are additional
- Xmenus (called Tools Menus) that can be set up by the user.
- X
- XBrowser Menu
- X
- X Open
- X
- X This entry is equivalent to double-clicking the selected
- X file. It is included for consistency with Workbench. Strictly
- X speaking it should be in the Actions menu, but it seems to fit
- X here better.
- X
- X Close
- X
- X This entry is equivalent to clicking the active window's
- X close gadget. Again, it's included for consistency with the
- X Workbench.
- X
- X Rescan
- X
- X This entry requests Browser to re-scan the directory displayed
- X in the active window. This is equivalent to, but a lot more convenient
- X than, closing and re-opening the window. I suppose I could poll the
- X disk for these, but if you use floppies much this becomes slightly
- X inconvenient.
- X
- X Show >
- X
- X This entry selects whether files, files and sizes, or full
- X file information is displayed for the current window. It has been
- X extended since 1.6a and is now provides a full set of options.
- X
- X Sel All
- X
- X This selects all files in the active window. Actually, it
- X toggles the selection of each file. Currently selected files will
- X be deselected.
- X
- X Sel Match...
- X
- X This is the same as Sel All, except that a pattern may be
- X provided to further restrict the selection.
- X
- X Options
- X
- X This allows you to modify the global behaviour of Browser
- X to some extent:
- X
- X X Toggle Selections
- X
- X This affects whether a selection through the menu,
- X or a shift-click, will deselect an already selected file.
- X
- X X Move files into subdirectories
- X
- X This effects whether you can move files into a
- X subdirectory by dragging them to it and releasing the mouse
- X button when the mouse is over the directory's name. If this
- X is not set you have to open the directory first.
- X
- X X Ask before moving into subdirectories
- X
- X If you permit files to be moved into subdirectories,
- X this determines if Browser will prompt you beforehand.
- X
- X Quit
- X
- X This selection closes all windows and terminates Browser.
- X
- XActions Menu
- X
- X The entries in this menu act on files rather than changing the state
- Xof Browser.
- X
- X WB Tool
- X
- X The currently selected file (singular) is entered into the
- X Tools menu as a workbench tool.
- X
- X CLI Tool...
- X
- X The currently selected file (singular) is entered into the
- X Tools menu as a CLI tool. Browser will pop up a requestor and allow
- X you to add additional arguments.
- X
- X Rename...
- X
- X The currently selected file (singular) is renamed. Browser
- X will pop up a requestor and allow you to enter the new name.
- X
- X Duplicate...
- X
- X The currently selected file (singular) is duplicated. Browser
- X will pop up a requestor and allow you to edit the new name (generated
- X by BumpRevision: "file" becomes "copy of file", and so on).
- X
- X Make Dir...
- X
- X Creates a new directory in the currently active window.
- X Browser will pop up a requestor and allow you to specify the name of
- X the new directory.
- X
- X Delete
- X
- X Deletes all selected files. This will only delete directories
- X if they happen to be empty.
- X
- X Delete All
- X
- X Deletes all selected files AND directories, recursively.
- X
- XTools Menus
- X
- X These menus (starting with Tools) are initially empty. They are filled
- Xin by selecting "Add * Tool" or from the file "s:browser.inittab". When you
- Xselect an entry in these menus they're run (either as workbench or CLI
- Xprograms) with all selected files being passed to the program. If you have
- Xa choice, you should make a program run under the Workbench... it's MUCH
- Xmore reliable.
- X
- XEnvironment
- X
- X Browser can itself be run from either the Workbench or the CLI. The
- Xseparate "bgbrowser" program no longer exists... use "runback" or some
- Xequivalent program if you want to run browser in a detached mode.
- X
- X Browser uses a file, "s:browser.inittab", to pre-load the command
- Xmenus. Each line in the file is a separate menu item, made up of 5 fields
- Xseparated by semicolons:
- X
- X name;environment;command;stack;window
- X
- X The first field is the name that is to appear in the menu. This
- Xname can be preceded by the name of the menu to insert it in followed by
- Xa period. If the menu name is left off, the "Tools" menu will be used.
- XFor example, "Applications.Terminal Emulator" will create a menu entry
- Xfor "Terminal Emulator" and install it in the "Applications" menu. If the
- Xmenu doesn't already exist, it will be created.
- X
- X The two environments currently supported are the CLI and the
- XWorkbench. Project files (such as AmigaBasic programs) aren't supported
- Xthrough the menu system at this time, though they may be at a later date.
- XThey do work just fine when you double-click them.
- X
- X If our terminal emulator was to be run as a Workbench program, then
- Xthis field should contain "Workbench". If it can't run under the Workbench,
- Xthen it should contain "CLI". It is better, if possible, to run programs
- Xunder the Workbench. It's a cleaner environment, and you don't get extra
- Xwindows cluttering up your display.
- X
- X The next field is the name of the command. This should contain the
- Xfull path name to the program. If the command is a CLI command, additional
- Xarguments can be included at this point. The names of any files highlighted
- Xwhen this menu is selected will be added to the end. If the command is
- Xa Workbench command, this should just be the program name. Highlighted
- Xfiles will be passed to the program in the Workbench Args structure.
- X
- X The next field is the stack size. It may be left off, and will
- Xdefault to 8K.
- X
- X The last field is the window. For a CLI command, this is the
- Xwindow that will be opened to run the CLI in. For a Workbench command,
- Xthis is the ToolWindow that will be passed to it. If it's left off a
- Xdefault will be used.
- X
- X Applications.Terminal Emulator;Workbench;sys:system/Termulator
- X
- XLimitations:
- X
- X The CLI capability occasionally leaves you in an interactive CLI
- Xafter you exit the program. This is caused by using one of the BREAK keys
- Xwhile you're in the program. I had to leave this in to get finicky CLI
- Xprograms, such as Manx 'Z' editor, to work properly.
- X
- X If you're copying a file to disk and you get a disk error,
- Xoccasionally browser will appear to ignore disk errors and keep on trying
- Xto write. Actually, Browser handles all disk errors that get reported to
- Xit. For some reason AmigaDOS doesn't report errors promptly. I suspect
- Xthis is related to requesting writes larger than a disk buffer, but I
- Xdon't plan on having Browser do anything about this in the near future.
- X
- X Browser seems to run just fine with only the standard 4K stack. The
- Xminimum environment you need to run browser is:
- X
- X libs (dir)
- X icon.library
- X
- XIf you also want to run CLI programs, you also need:
- X
- X c (dir)
- X cd EndCLI
- X Failat NewCLI
- X Run Stack
- X l (dir)
- X Ram-Handler
- X
- XThese are needed to run the little scripts Browser builds in RAM: when you
- Xrun a CLI program.
- X
- XAuthor:
- X
- X Peter da Silva
- X
- X U.S.Mail:
- X 15770 Bellaire Blvd. #107
- X Houston, TX 77083
- X
- X Phone:
- X +1 713 568 0480 (data: Taronga Park)
- X +1 713 274 5180 (work)
- X
- X Internet:
- X peter@taronga.hackercorp.com
- X Compuserve:
- X >internet:peter@taronga.hackercorp.com (preferred)
- X 70216,1076
- X
- X I'm currently getting a new domain name, so if your mail to
- Xtaronga.hackercorp.com bounces or is delayed, try taronga.com. If all
- Xelse fails I'm currently working at Ferranti International Controls
- XCorporation, so try peter@ferranti.com.
- X
- XDonations:
- X
- X If you find this program useful, you may send a donation to the
- Xauthor, Peter da Silva. For a donation of thirty dollars or more you will
- Xreceive the latest version of Browser (or, if you prefer, the next version
- Xif it ever comes out... as I said, 1.7 is likely to be the ultimate release).
- X
- X If you have been waiting for the next release and it hasn't got
- Xto you, call me or send me email. With this release I'm sending all the
- Xfolks who contributed the program and a copy of the source. You should get
- Xa copy in the mail soon.
- X
- XSponsors:
- X
- X The following people have donated money, and are willing to have
- Xtheir names up in lights. Thanks, folks. In no particular order...
- X
- X <CB>
- X Kent and Judy Polk
- X Burkard S. Kr|ger
- X D. Ballinger
- X Ron Harper
- X Steven D. Kapplin
- X David Allen
- X Glen Fullmer
- X Ed Vishoot
- X Jeff Van Epps
- X P. Wright
- X Heinz Mathalm
- X Blaine Gardner
- X Liam Healy
- X Johan Widin
- X D. Ratliff
- X T. J. Pagano
- X J|rgen Klawitter
- X Ulrich Denker
- X Rick Jones
- X Guenther Engelhardt
- X
- XAnd special thanks to my wife, Stephanie, who talked me into doing this
- Xrelease.
- END_OF_FILE
- if test 12580 -ne `wc -c <'browser.doc'`; then
- echo shar: \"'browser.doc'\" unpacked with wrong size!
- fi
- # end of 'browser.doc'
- fi
- if test -f 'fonts.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fonts.h'\"
- else
- echo shar: Extracting \"'fonts.h'\" \(355 characters\)
- sed "s/^X//" >'fonts.h' <<'END_OF_FILE'
- X#ifndef FONTS_H
- X#define FONTS_H
- X#ifndef GRAPHICS_GFXBASE_H
- X#include <graphics/gfxbase.h>
- X#endif
- X#ifndef GRAPHICS_TEXT_H
- X#include <graphics/text.h>
- X#endif
- X
- Xextern struct GfxBase *GfxBase;
- X
- X#define FONTWIDTH (GfxBase->DefaultFont->tf_XSize)
- X#define FONTHEIGHT (GfxBase->DefaultFont->tf_YSize)
- X#define FONTBASELINE (GfxBase->DefaultFont->tf_Baseline)
- X#endif
- END_OF_FILE
- if test 355 -ne `wc -c <'fonts.h'`; then
- echo shar: \"'fonts.h'\" unpacked with wrong size!
- fi
- # end of 'fonts.h'
- fi
- if test -f 'goodies.readme' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'goodies.readme'\"
- else
- echo shar: Extracting \"'goodies.readme'\" \(451 characters\)
- sed "s/^X//" >'goodies.readme' <<'END_OF_FILE'
- XThe 'goodies' are sections of the source to Browser that I have previously
- Xreleased into the public domain, or that I got from the public domain. I
- Xfigure that you folks should benefit from them:
- X
- X PatMatch.c A very nice AmigaDOS-compatible regular expression parser.
- X menu.c A fairly clean way of dealing with lots of silly menus.
- X menu.h Needed for menu.c
- X fonts.h Needed for menu.c
- X vollist.c An Examine/ExNext type interface to the device list.
- END_OF_FILE
- if test 451 -ne `wc -c <'goodies.readme'`; then
- echo shar: \"'goodies.readme'\" unpacked with wrong size!
- fi
- # end of 'goodies.readme'
- fi
- if test -f 'menu.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'menu.c'\"
- else
- echo shar: Extracting \"'menu.c'\" \(8280 characters\)
- sed "s/^X//" >'menu.c' <<'END_OF_FILE'
- X/* easy menus: Copyright 1987 Peter da Silva, all rights reserved.
- X *
- X * Permission is granted to use this in any application, so long as
- X * this notice is retained in the source. Permission is granted to
- X * modify the code as you like, so long as this notice (between the
- X * first line beginning "easy menus" and the end of this paragraph,
- X * inclusive) is retained intact.
- X *
- X * Usage:
- X *
- X * #include "menu.h"
- X *
- X * struct MenuPtr menudata;
- X * struct MenuPtr *menuptr = &menudata;
- X *
- X * init_menus(menuptr); / * Just zero menu pointer out * /
- X *
- X * for(each menu item) {
- X * add_menu(menuptr, menu, item, subitem, flags);
- X * }
- X *
- X * Flags:
- X * SUBITEM_NOCHECK -- subitem does not require a checkmark.
- X * SUBITEM_SELECTOR -- subitem is a 1 of n selector, use mutual-exclude.
- X * SUBITEM_TOGGLE -- subitem is a toggled flag.
- X * SUBITEM_SELECTED -- defaults to checked.
- X *
- X *
- X * SetMenuStrip(yourwindow, menuptr->MenuBar);
- X *
- X * ...
- X *
- X * ClearMenuStrip(yourwindow);
- X *
- X * trash_menus(menuptr);
- X *
- X * Notes:
- X *
- X * if you don't want any subitems, use zero for the subitem value.
- X *
- X * subitem is always initialised as a CHECKIT item with all the other
- X * subitems mutually excluded.
- X *
- X * it is intended that the menu be set up with all action items in
- X * the first level of the menu, and all toggles in the second level...
- X * this is a piece of blatant authoritarianism on my part. I've seen
- X * too many menus with no rhyme or reason. Look at AmigaTerm (the term
- X * program that comes with the Amiga modem) some time. Baud rate has
- X * an item all by itself, but word size is hidden off in a menu with
- X * things like bell sound.
- X *
- X * the appearance of the menus produced by this is (in my humble
- X * opinion) good. I took some care making text centered in menu boxes,
- X * for example.
- X */
- X#include <exec/memory.h>
- X#include <intuition/intuition.h>
- X#include "menu.h"
- X#include "fonts.h"
- X
- X/* Forward prototypes */
- Xstatic void nudge(struct MenuItem *item, int delta);
- Xstatic struct Menu *
- X new_menu(struct MenuPtr *menuptr, char *name);
- Xstatic struct MenuItem *
- X new_item(struct MenuPtr *menuptr,
- X struct Menu *menu, UBYTE *name);
- Xstatic struct MenuItem *
- X new_subitem(struct MenuPtr *menuptr,
- X struct MenuItem *item, UBYTE *name, long flags);
- X
- X/*
- Xstruct MenuPtr {
- X struct Menu *MenuBar;
- X struct Remember *MenuMemory;
- X};
- X*/
- X
- Xchar *AllocRemember();
- X
- Xstatic struct Menu *new_menu();
- Xstatic struct MenuItem *new_item(), *new_subitem();
- X
- X#define TOMENUNUM(i,j,k) (SHIFTMENU(i)|SHIFTITEM(j)|SHIFTSUB(k))
- X#define TextLen(s) (strlen(s)*FONTWIDTH)
- X
- Xvoid trash_menus(struct MenuPtr *menuptr)
- X{
- X FreeRemember(&menuptr->MenuMemory, 1);
- X menuptr->MenuMemory = 0;
- X menuptr->MenuBar = 0;
- X}
- X
- Xvoid init_menus(struct MenuPtr *menuptr)
- X{
- X menuptr->MenuMemory = 0;
- X menuptr->MenuBar = 0;
- X}
- X
- Xint add_menu(
- X struct MenuPtr *menuptr,
- X char *menuname,
- X char *itemname,
- X char *subitemname,
- X long flags)
- X{
- X int i, j, k;
- X struct Menu *menu;
- X struct MenuItem *item;
- X struct MenuItem *subitem;
- X
- X if(menuptr->MenuBar) {
- X for(i = 0, menu = menuptr->MenuBar;
- X menu;
- X menu = menu->NextMenu, i++
- X )
- X if(strcmp(menuname, menu->MenuName)==0)
- X break;
- X if(!menu)
- X menu = new_menu(menuptr, menuname);
- X if(!menu)
- X return MENUNULL;
- X } else {
- X i = 0;
- X menu = new_menu(menuptr, menuname);
- X if(!menu)
- X return MENUNULL;
- X }
- X for(j = 0, item = menu->FirstItem;
- X item;
- X item = item->NextItem, j++
- X ) {
- X struct IntuiText *text;
- X text = (struct IntuiText *)item->ItemFill;
- X if(strcmp(itemname, text->IText) == 0)
- X break;
- X }
- X if(subitemname) {
- X if(!item)
- X item = new_item(menuptr, menu, (UBYTE *)itemname);
- X if(!item)
- X return MENUNULL;
- X for(k = 0, subitem = item->SubItem;
- X subitem;
- X subitem = subitem->NextItem, k++
- X ) {
- X struct IntuiText *text;
- X text = (struct IntuiText *)subitem->ItemFill;
- X if(strcmp(subitemname, text->IText) == 0)
- X break;
- X }
- X if(!subitem)
- X subitem = new_subitem(menuptr, item, (UBYTE *)subitemname, flags);
- X if(!subitem)
- X return MENUNULL;
- X return TOMENUNUM(i, j, k);
- X } else {
- X if(!item)
- X item = new_item(menuptr, menu, (UBYTE *)itemname);
- X if(!item)
- X return MENUNULL;
- X return TOMENUNUM(i, j, NOSUB);
- X }
- X}
- X
- Xstatic struct Menu *
- Xnew_menu(struct MenuPtr *menuptr, char *name)
- X{
- X struct Menu *menu;
- X
- X menu = (struct Menu *)AllocRemember(
- X &menuptr->MenuMemory,
- X sizeof(struct Menu),
- X MEMF_PUBLIC);
- X if(!menu)
- X return 0;
- X menu->NextMenu = NULL;
- X menu->LeftEdge = 0;
- X menu->TopEdge = 0;
- X menu->Width = TextLen(name)+FONTWIDTH;
- X menu->Height = 0;
- X menu->Flags = MENUENABLED;
- X menu->MenuName = name;
- X menu->FirstItem = 0;
- X if(menuptr->MenuBar) {
- X struct Menu *ptr, *prev;
- X for(ptr = menuptr->MenuBar; ptr; ptr=ptr->NextMenu) {
- X menu->LeftEdge += ptr->Width;
- X prev = ptr;
- X }
- X prev->NextMenu = menu;
- X } else {
- X menuptr->MenuBar = menu;
- X }
- X
- X return menu;
- X}
- X
- Xstatic struct MenuItem *
- Xnew_item(struct MenuPtr *menuptr, struct Menu *menu, UBYTE *name)
- X{
- X struct MenuItem *item;
- X struct IntuiText *text;
- X
- X item = (struct MenuItem *)AllocRemember(
- X &menuptr->MenuMemory,
- X sizeof(struct MenuItem),
- X MEMF_PUBLIC);
- X if(!item)
- X return 0;
- X text = (struct IntuiText *)AllocRemember(
- X &menuptr->MenuMemory,
- X sizeof(struct IntuiText),
- X MEMF_PUBLIC);
- X if(!text)
- X return 0;
- X
- X text->FrontPen = AUTOFRONTPEN;
- X text->BackPen = AUTOBACKPEN;
- X text->DrawMode = JAM2;
- X text->LeftEdge = 1;
- X text->TopEdge = 1;
- X text->ITextFont = NULL;
- X text->IText = name;
- X text->NextText = NULL;
- X
- X item->NextItem = NULL;
- X item->LeftEdge = 0;
- X item->TopEdge = 0;
- X item->Width = IntuiTextLength(text)+2;
- X if(item->Width <= menu->Width)
- X item->Width = menu->Width+1;
- X item->Height = FONTHEIGHT+1;
- X item->Flags = ITEMTEXT|HIGHCOMP|ITEMENABLED;
- X item->MutualExclude = 0;
- X item->ItemFill = (APTR)text;
- X item->SelectFill = NULL;
- X item->Command = 0;
- X item->SubItem = NULL;
- X item->NextSelect = NULL;
- X
- X if(menu->FirstItem) {
- X struct MenuItem *ptr, *prev;
- X for(ptr = menu->FirstItem; ptr; ptr=ptr->NextItem) {
- X if(item->Width > ptr->Width) {
- X if(ptr->SubItem)
- X nudge(ptr->SubItem, item->Width-ptr->Width);
- X ptr->Width = item->Width;
- X } else if(ptr->Width>item->Width)
- X item->Width = ptr->Width;
- X prev = ptr;
- X }
- X item->TopEdge = prev->TopEdge + prev->Height;
- X prev->NextItem = item;
- X } else {
- X menu->FirstItem = item;
- X }
- X
- X return item;
- X}
- X
- Xstatic void nudge(struct MenuItem *item, int delta)
- X{
- X while(item) {
- X item->LeftEdge += delta;
- X item = item->NextItem;
- X }
- X}
- X
- Xstatic struct MenuItem *
- Xnew_subitem(
- X struct MenuPtr *menuptr,
- X struct MenuItem *item,
- X UBYTE *name,
- X long flags)
- X{
- X struct MenuItem *subitem;
- X struct IntuiText *text;
- X
- X subitem = (struct MenuItem *)AllocRemember(
- X &menuptr->MenuMemory,
- X sizeof(struct MenuItem),
- X MEMF_PUBLIC);
- X if(!subitem)
- X return 0;
- X text = (struct IntuiText *)AllocRemember(
- X &menuptr->MenuMemory,
- X sizeof(struct IntuiText),
- X MEMF_PUBLIC);
- X if(!text)
- X return 0;
- X
- X text->FrontPen = AUTOFRONTPEN;
- X text->BackPen = AUTOBACKPEN;
- X text->DrawMode = JAM2;
- X text->LeftEdge = 1;
- X if(flags != SUBITEM_NOCHECK) text->LeftEdge += CHECKWIDTH;
- X text->TopEdge = 1;
- X text->ITextFont = NULL;
- X text->IText = name;
- X text->NextText = NULL;
- X
- X subitem->NextItem = NULL;
- X subitem->LeftEdge = item->Width;
- X subitem->TopEdge = 0;
- X subitem->Width = IntuiTextLength(text)+2;
- X if(flags != SUBITEM_NOCHECK) subitem->Width += CHECKWIDTH;
- X subitem->Height = FONTHEIGHT+1;
- X subitem->Flags = ITEMTEXT|ITEMENABLED|HIGHCOMP;
- X subitem->MutualExclude = 0;
- X if(flags != SUBITEM_NOCHECK) {
- X subitem->Flags |= CHECKIT;
- X if(flags & SUBITEM_TOGGLE) subitem->Flags |= MENUTOGGLE;
- X if(flags & SUBITEM_SELECTED) subitem->Flags |= CHECKED;
- X }
- X subitem->ItemFill = (APTR)text;
- X subitem->SelectFill = NULL;
- X subitem->Command = 0;
- X subitem->SubItem = NULL;
- X subitem->NextSelect = NULL;
- X
- X if(item->SubItem) {
- X struct MenuItem *ptr, *prev;
- X int i;
- X for(i=0, ptr = item->SubItem; ptr; i++, ptr=ptr->NextItem) {
- X if(subitem->Width > ptr->Width)
- X ptr->Width = subitem->Width;
- X else if(ptr->Width>subitem->Width)
- X subitem->Width = ptr->Width;
- X prev = ptr;
- X }
- X subitem->TopEdge = prev->TopEdge + prev->Height;
- X if(flags & SUBITEM_SELECTOR)
- X subitem->MutualExclude = ~(1<<i);
- X prev->NextItem = subitem;
- X } else {
- X item->SubItem = subitem;
- X if(flags & SUBITEM_SELECTOR)
- X subitem->MutualExclude = ~1;
- X }
- X
- X return subitem;
- X}
- END_OF_FILE
- if test 8280 -ne `wc -c <'menu.c'`; then
- echo shar: \"'menu.c'\" unpacked with wrong size!
- fi
- # end of 'menu.c'
- fi
- if test -f 'menu.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'menu.h'\"
- else
- echo shar: Extracting \"'menu.h'\" \(359 characters\)
- sed "s/^X//" >'menu.h' <<'END_OF_FILE'
- Xstruct MenuPtr {
- X struct Menu *MenuBar;
- X struct Remember *MenuMemory;
- X int next_id;
- X};
- X
- X/* flags */
- X#define SUBITEM_NOCHECK 0x0 /* subitem does not require a checkmark. */
- X#define SUBITEM_SELECTOR 0x10 /* subitem is a 1 of n selector */
- X#define SUBITEM_TOGGLE 0x20 /* subitem is a toggled flag. */
- X#define SUBITEM_SELECTED 0x01 /* defaults to checked. */
- END_OF_FILE
- if test 359 -ne `wc -c <'menu.h'`; then
- echo shar: \"'menu.h'\" unpacked with wrong size!
- fi
- # end of 'menu.h'
- fi
- if test -f 'vollist.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'vollist.c'\"
- else
- echo shar: Extracting \"'vollist.c'\" \(1578 characters\)
- sed "s/^X//" >'vollist.c' <<'END_OF_FILE'
- X#include <libraries/dosextens.h>
- X#include <stdio.h>
- X#ifdef DEBUG
- X#include "debug.h"
- X#endif
- X/* Fakes an Examine/ExNext interface to the device list. Call OpenVolList
- X * first, then ReadVolList(fib), and finally CloseVolList. This last is
- X * a dummy, but it's handy if you want to be safe and put a forbid/permit
- X * around the whole thing.
- X */
- X
- X#define toAPTR(b) ((b)<<2)
- X#define toBPTR(a) ((a)>>2)
- X
- Xstruct DeviceList *list;
- X
- Xvoid OpenVolList(void)
- X{
- X extern struct DosLibrary *DOSBase;
- X struct RootNode *root;
- X struct DosInfo *info;
- X
- X root = (struct RootNode *)DOSBase -> dl_Root;
- X info = (struct DosInfo *)toAPTR(root->rn_Info);
- X list = (struct DeviceList *)toAPTR(info->di_DevInfo);
- X}
- X
- Xint ReadVolList(struct FileInfoBlock *fib)
- X{
- X struct DeviceList *next;
- X
- X while(list) {
- X next = (struct DeviceList *)toAPTR(list->dl_Next);
- X if(list->dl_Type == DLT_VOLUME ||
- X list->dl_Type == DLT_DIRECTORY) {
- X char *ptr;
- X int count;
- X ptr = (char *)toAPTR((BPTR)list->dl_Name);
- X count = *ptr++;
- X if(count > 106)
- X count = 106;
- X strncpy(fib->fib_FileName, ptr, count);
- X fib->fib_FileName[count++] = ':';
- X fib->fib_FileName[count] = 0;
- X if(strcmp(fib->fib_FileName, "RAM Disk:") == 0)
- X strcpy(fib->fib_FileName, "RAM:");
- X fib->fib_DiskKey = 0;
- X fib->fib_DirEntryType = list->dl_Type;
- X fib->fib_Protection = 0;
- X fib->fib_EntryType = list->dl_Type;
- X fib->fib_Size = 0;
- X fib->fib_NumBlocks = 0;
- X fib->fib_Date = list->dl_VolumeDate;
- X fib->fib_Comment[0] = 0;
- X list = next;
- X return 1;
- X }
- X list = next;
- X }
- X return 0;
- X}
- X
- Xvoid CloseVolList(void)
- X{
- X}
- END_OF_FILE
- if test 1578 -ne `wc -c <'vollist.c'`; then
- echo shar: \"'vollist.c'\" unpacked with wrong size!
- fi
- # end of 'vollist.c'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
- Mail comments to the moderator at <amiga-request@uunet.uu.net>.
- Post requests for sources, and general discussion to comp.sys.amiga.misc.
-